﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using PowerHub.MES.EFBase;
using PowerHub.MES.Entities;
using PowerHub.MES.Entities.Log;
using PowerHub.MES.IRepository.ILog;
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace PowerHub.MES.Common.Utility
{
    public class RequestLoggingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IServiceProvider _serviceProvider;
        public RequestLoggingMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
        {
            _next = next;
            _serviceProvider = serviceProvider;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 获取请求的 IP 地址
            var ipAddress = context.Connection.RemoteIpAddress;
            var ipAddressString = ipAddress?.ToString() ?? "未知IP";

            // 清理 IP 地址
            ipAddressString = CleanIpAddress(ipAddressString);

            // 获取请求的 URL
            var requestUrl = context.Request.Path.ToString();

            // 获取请求的功能名称
            var functionName = GetFunctionNameFromRequest(context);

            // 获取实际位置信息
            var locationInfo = await GetLocationInfoAsync(ipAddressString);

            // 调用下一个中间件，继续处理请求
            await _next(context);

            // 获取请求的返回状态
            var responseStatus = context.Response.StatusCode;

            // 获取请求的设备信息
            var osInfo = GetOperatingSystemInfo(context.Request.Headers["User-Agent"].ToString());

            // 记录日志
            using (var scope = _serviceProvider.CreateScope())
            {
                var log_RequestRepository = scope.ServiceProvider.GetRequiredService<ILog_RequestRepository>();
                Log_Request log_Request = new Log_Request(ipAddressString, locationInfo, requestUrl, functionName, osInfo, responseStatus);
                await log_RequestRepository.CreateLog_RequestAsync(log_Request);
            }
        }

        /// <summary>
        /// 去掉ip像 ::ffff: 和 :: 这样的前缀
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        private string CleanIpAddress(string ipAddress)
        {
            if (string.IsNullOrEmpty(ipAddress))
            {
                return "未知IP";
            }

            // 去除 IPv4 映射 IPv6 地址的 "::ffff:" 前缀
            if (ipAddress.StartsWith("::ffff:"))
            {
                ipAddress = ipAddress.Substring(7);
            }

            // 处理其他前缀（例如 "::" ）
            if (ipAddress.StartsWith("::"))
            {
                ipAddress = ipAddress.Substring(2);
            }

            return ipAddress;
        }
        /// <summary>
        /// 获取请求的功能
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private string GetFunctionNameFromRequest(HttpContext context)
        {
            // 获取当前请求的 Endpoint 信息
            var endpoint = context.GetEndpoint();
            if (endpoint != null)
            {
                var actionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
                if (actionDescriptor != null)
                {
                    // 获取方法上的 FunctionDescriptionAttribute 特性
                    var actionMethod = actionDescriptor.MethodInfo;
                    var functionDescription = actionMethod.GetCustomAttributes<FunctionDescriptionAttribute>().FirstOrDefault();
                    return functionDescription?.Description ?? $"{actionDescriptor.ControllerName} - {actionDescriptor.ActionName}";
                }
            }
            return "未知功能";
        }

        /// <summary>
        /// 获取地理地址信息
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        private async Task<string> GetLocationInfoAsync(string ipAddress)
        {
            if (string.IsNullOrEmpty(ipAddress))
            {
                return "未知位置";
            }

            // 调用高德地图根据IP 地址地理位置 
            try
            {
                var aa = await GaoDeMapAPI.GetIPLocation(ipAddress);
                return $"{aa.province}, {aa.city}";
            }
            catch
            {
                return "位置查找失败";
            }
        }

        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <param name="userAgent"></param>
        /// <returns></returns>
        private string GetOperatingSystemInfo(string userAgent)
        {
            // 使用正则表达式匹配操作系统信息
            var osRegex = new Regex(@"\(([^)]+)\)");
            var match = osRegex.Match(userAgent);
            if (match.Success)
            {
                // 提取操作系统信息
                var osInfo = match.Groups[1].Value;
                return osInfo;
            }
            return "未知操作系统";
        }
    }
}
